<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>2018/11/29</title>
    <!--好的代码像粥一样,是得用时间和精力熬的。-->
</head>
<body>
<script>
    //从数组和对象中提取值，对变量进行赋值，这被称为解构（Destructuring）。
    //es5 为变量赋值，只能直接指定值。
    // let a = 1;
    // let b = 2;
    // let c = 3;
    // //es6  从数组中提取值，按照对应位置，对变量赋值。
    // let [a, b, c] = [1, 2, 3];

    //使用嵌套数组进行解构的例子
    // 如果解构不成功，变量的值就等于undefined。
    // let [foo, [[bar], baz]] = [1, [[2], 3]];
    // console.log(foo); // 1
    // console.log(bar); // 2
    // console.log(baz); // 3

    // let [ , , third] = ["foo", "bar", "baz"];
    // console.log(third); // "baz"

    // let [x, , y] = [1, 2, 3];
    // console.log(x); // 1
    // console.log(y); // 3

    // let [head, ...tail] = [1, 2, 3, 4];
    // console.log(head); // 1
    // console.log(tail); // [2, 3, 4]

    // let [x, y, ...z] = ['a'];
    // console.log(x);// "a"
    // console.log(y);// undefined
    // console.log(z); // []

    // let [foo] = [];
    // console.log(foo); //undefined

    // let [bar, foo] = [1];
    // console.log(bar);  //1
    // console.log(foo);  //undefined

    //另一种情况是不完全解构，即等号左边的模式，只匹配一部分的等号右边的数组。
    // 这种情况下，解构依然可以成功。
    //属于不完全解构，但是可以成功。
    // let [x, y] = [1, 2, 3];
    // console.log(x); // 1
    // console.log(y); // 2

    // let [a, [b], d] = [1, [2, 3], 4];
    // console.log(a); // 1
    // console.log(b); // 2
    // console.log(d); // 4

    //报错
    // let [foo1] = 1;
    // console.log(foo1); //TypeError: 1 is not iterable
    // let [foo2] = false;
    // console.log(foo2);
    // let [foo3] = NaN;
    // console.log(foo3);
    // let [foo4] = undefined;
    // console.log(foo4);
    // let [foo5] = null;
    // console.log(foo5);
    // let [foo6] = {};
    // console.log(foo6);

    //对于 Set 结构，也可以使用数组的解构赋值。
    // let [x, y, z] = new Set(['a', 'b', 'c']);
    // console.log(x); // "a"

//只要某种数据结构具有 Iterator 接口，都可以采用数组形式的解构赋值。
// fibs是一个 Generator 函数（参见《Generator 函数》一章），原生具有 Iterator 接口。解构赋值会依次从这个接口获取值。
//     function* fibs() {
//         let a = 0;
//         let b = 1;
//         while (true) {
//             yield a;
//             [a, b] = [b, a + b];
//         }
//     }
//     let [first, second, third, fourth, fifth, sixth] = fibs();
//     console.log(sixth); // 5

//解构赋值允许指定默认值。
    //ES6 内部使用严格相等运算符（===），判断一个位置是否有值。
    // 所以，只有当一个数组成员严格等于undefined，默认值才会生效。
    // let [foo = true] = [];
    // console.log(foo); // true
    // let [x, y = 'b'] = ['a']; // x='a', y='b'
    // let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

    //如果一个数组成员是null，默认值就不会生效，因为null不严格等于undefined。
    // let [x = 1] = [undefined];
    // console.log(x);  // 1
    // let [y = 1] = [null];
    // console.log(y);  // null

    //如果默认值是一个表达式，那么这个表达式是惰性求值的，即只有在用到的时候，才会求值。
    // function f() {
    //     console.log('aaa');
    // }
    // let [x = f()] = [1];

    // console.log(x);
    //因为x能取到值，所以函数f根本不会执行。上面的代码其实等价于下面的代码。
    // let x;
    // if ([1][0] === undefined) {
    //     x = f();
    // } else {
    //     x = [1][0];
    // }

    //默认值可以引用解构赋值的其他变量，但该变量必须已经声明。
    // let [x = 1, y = x] = [];
    // console.log(x); // x=1
    // console.log(y); // y=1
    // let [x = 1, y = x] = [2];    // x=2; y=2
    // let [x = 1, y = x] = [1, 2]; // x=1; y=2
    // let [x = y, y = 1] = [];     // ReferenceError: y is not defined

//对象的解构赋值
    //解构不仅可以用于数组，还可以用于对象。
    let {foo,bar} = {foo:'aaa',bar:'bbb'};
    console.log(foo);
    console.log(bar);


</script>

</body>
</html>
